package org.ricks.net.util;

import java.nio.ByteBuffer;

public abstract class HashUtils {


    private static final int P = 16777619;
    private static final int INIT_HASH = (int) 2166136261L;

    /**
     * 改进的32位FNV算法1
     *
     * @param data 数组
     * @return hash结果
     */
    public static int fnvHash(byte[] data) {
        var hash = INIT_HASH;
        for (byte b : data) {
            hash = (hash ^ b) * P;
        }
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
        return Math.abs(hash);
    }

    /**
     * 改进的32位FNV算法1
     *
     * @param object 计算hash的对象，会调用toString方法
     * @return hash结果
     */
    public static int fnvHash(Object object) {
        var hash = object.toString().chars().reduce(INIT_HASH, (left, right) -> (left ^ right) * P);
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
        return Math.abs(hash);
    }


    public static int murmurHash3(byte[] data, int seed) {
        final int c1 = 0xcc9e2d51, c2 = 0x1b873593;
        int h1 = seed;
        int len = data.length;

        // 分块处理（每4字节）
        for (int i = 0; i < len / 4; i++) {
            int k = ByteBuffer.wrap(data, i*4, 4).getInt();
            k *= c1;
            k = Integer.rotateLeft(k, 15);
            k *= c2;
            h1 ^= k;
            h1 = Integer.rotateLeft(h1, 13);
            h1 = h1 * 5 + 0xe6546b64;
        }

        // 处理尾部字节
        int k = 0;
        switch (len % 4) {
            case 3: k ^= (data[len-3] & 0xFF) << 16;
            case 2: k ^= (data[len-2] & 0xFF) << 8;
            case 1: k ^= (data[len-1] & 0xFF);
                k *= c1; k = Integer.rotateLeft(k, 15); k *= c2; h1 ^= k;
        }

        // 最终混合（雪崩效应）
        h1 ^= len;
        h1 ^= h1 >>> 16;
        h1 *= 0x85ebca6b;
        h1 ^= h1 >>> 13;
        h1 *= 0xc2b2ae35;
        h1 ^= h1 >>> 16;
        return h1;
    }


}

